/*
 ********************************************************************************
 * @FileName  : button.c
 * @CreateDate: 2021-8-7
 * @Author    : GaoQiu
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 ********************************************************************************
 */

#include "button.h"
#include "pan10x_gpio.h"

BtnData_t btnData;

#if CFG_BTN_IT_MODE_EN
#define BTN_FILTER_NUM  2
#else
#define BTN_FILTER_NUM  4
#endif

typedef struct{
	BtnMask_t   pressedMask;
	BtnMask_t   history[BTN_FILTER_NUM];
	BtnMask_t   lastPressedMask;
	uint16_t    pins[BTN_MAX_NUM];
	uint8_t     btnMap[BTN_MAX_NUM];
	uint8_t     btnCnt;
	BtnEvtHandlerCb_t  BtnEvtHandlerCb;
}BtnCb_t;

BtnCb_t btnCb;

 bool_t Btn_IsChanged(uint32_t pressedMask)
 {
	 bool_t btnChanged = false;

	 for(int i=BTN_FILTER_NUM-1; i>0; --i){
		 btnCb.history[i] = btnCb.history[i-1];
	 }
	 btnCb.history[0] = pressedMask;

#if BTN_FILTER_NUM == 4
	 if(btnCb.history[0] == btnCb.history[1] && btnCb.history[1] == btnCb.history[2] &&
	    btnCb.history[0] != btnCb.lastPressedMask){
		 btnChanged = true;

		 btnCb.lastPressedMask = btnCb.history[0];
	 }
#elif BTN_FILTER_NUM == 2
	 if(btnCb.history[0] == btnCb.history[1] &&
	    btnCb.history[0] != btnCb.lastPressedMask){
		 btnChanged = true;

		 btnCb.lastPressedMask = btnCb.history[0];
	 }
#endif
	 return btnChanged;
 }

bool_t Btn_Scan(void)
{
	btnData.cnt = 0;

	btnCb.pressedMask = 0;

	for(int i=0; i<btnCb.btnCnt; i++)
	{
		if(GPIO_ReadInputBit(btnCb.pins[i]) == BTN_VALID_LVL){
			btnCb.pressedMask |= BIT(i);
		}
	}

	//TRACK("PressedMask:0x%08x, lastMask:0x%08x\n",btnCb.pressedMask, btnCb.lastPressedMask);

	bool_t btnChanged = Btn_IsChanged(btnCb.pressedMask);
	if(btnChanged)
	{
		for(int i=0; i<btnCb.btnCnt; i++)
		{
			if(btnCb.pressedMask & BIT(i)){
				btnData.code[btnData.cnt++] = btnCb.btnMap[i];
			}
		}
	}

	return btnChanged;
}

BtnData_t *Btn_GetData(void)
{
	return &btnData;
}


void Btn_Init(void)
{
	uint16_t pins[] = BTN_PINS;
	uint8_t map[]   = BTN_MAPS;

	memset(&btnCb,0, sizeof(BtnCb_t));
	btnCb.btnCnt = sizeof(map);

	for(int i=0; i<btnCb.btnCnt; i++){
		btnCb.pins[i] = pins[i];
	}
	memcpy(btnCb.btnMap, map, btnCb.btnCnt);

	for(int i=0; i<btnCb.btnCnt; i++)
	{
		GPIO_Init(btnCb.pins[i], GPIO_Mode_In);
		GPIO_SetPullUp(btnCb.pins[i], 1); 

	#if CFG_BTN_IT_MODE_EN
		GPIO_SetITEnable(btnCb.pins[i], GPIO_IT_Mode_Falling);
	  #ifdef IP_108
		GPIO_SetDebounceEnable(btnCb.pins[i], DISABLE);
	  #elif defined(IP_107)
		GPIO_SetDebounceEnable(btnCb.pins[i], DISABLE);
		//GPIO_DB->DBCTL |= 0x02;
	  #endif
		GPIO_DB->DBCTL |= BIT(4);// Select DB clock to 32K
		RCC_Wait3VSync();
	#endif
	}

#if CFG_BTN_IT_MODE_EN
  #ifdef IP_108
	NVIC_EnableIRQ(GPIO_IRQn);

  #elif defined(IP_107)
//	NVIC_SetPriority(GPIO0_IRQn, 1);
//	NVIC_SetPriority(GPIO1_IRQn, 1);
	NVIC_EnableIRQ(GPIO0_IRQn);
	NVIC_EnableIRQ(GPIO1_IRQn);
  #endif
#endif
}

void Btn_RegisterEvtHandler(BtnEvtHandlerCb_t func)
{
	btnCb.BtnEvtHandlerCb = func;
}

#if CFG_BTN_IT_MODE_EN
uint8_t Btn_IRQHandler(uint16_t GPIO_Pxx)
{
	uint8_t flag = 0;

	if(GPIO_GetITState(GPIO_Pxx))
	{
		flag++;

		GPIO_SetITDisable(GPIO_Pxx);
		if(GPIO_ReadInputBit(GPIO_Pxx) == 0){
			GPIO_SetITEnable(GPIO_Pxx, GPIO_IT_Mode_Rising);
			//TRACK("-key pressed - gpio %04x\r\n",GPIO_Pxx);
		}
		else if(GPIO_ReadInputBit(GPIO_Pxx) == 1){
			GPIO_SetITEnable(GPIO_Pxx, GPIO_IT_Mode_Falling);
			//TRACK("-key release\r\n");
		}
		else{
			//TRACK_ERR("error\r\n");
		}
	}
	return flag;
}

#ifdef IP_108
void GPIO_IRQHandler(void)
{
#ifdef PAN10x_DK
	uint8_t flag = Btn_IRQHandler(GPIO_P04);
	flag += Btn_IRQHandler(GPIO_P05);
	flag += Btn_IRQHandler(GPIO_P56);
#elif defined(PAN10x_DG)
	uint8_t flag = Btn_IRQHandler(GPIO_P10);
	flag += Btn_IRQHandler(GPIO_P11);
#else
	#error "[Button] button interrupt not support..."
#endif

	if(flag && btnCb.BtnEvtHandlerCb){
		btnCb.BtnEvtHandlerCb();
	}

	uint32_t intState = P0->INTSRC & 0xff;
	P0->INTSRC |= intState;

	intState = P1->INTSRC & 0xff;
	P1->INTSRC |= intState;

	intState = P2->INTSRC & 0xff;
	P2->INTSRC |= intState;

	intState = P3->INTSRC & 0xff;
	P3->INTSRC |= intState;

	intState = P4->INTSRC & 0xff;
	P4->INTSRC = intState;

	intState = P5->INTSRC & 0xff;
	P5->INTSRC = intState;
}

#elif defined(IP_107)
void GPIO0_IRQHandler(void)
{
	uint8_t flag = 0;
	flag  = Btn_IRQHandler(GPIO_P02);
	flag += Btn_IRQHandler(GPIO_P06);

	if(flag && btnCb.BtnEvtHandlerCb){
		btnCb.BtnEvtHandlerCb();
	}

	/* Clear IT State */
	uint32_t intState = P0->INTSRC & 0xff;
	P0->INTSRC = intState;
}

void GPIO1_IRQHandler(void)
{
	uint8_t flag = 0;
	flag  = Btn_IRQHandler(GPIO_P12);

	if(flag && btnCb.BtnEvtHandlerCb){
		btnCb.BtnEvtHandlerCb();
	}

	/* Clear IT State */
	uint32_t intState = P1->INTSRC & 0xff;
	P1->INTSRC = intState;
}
#endif
#endif


